/***********************************************************************************
**  
* @copyright (c) 2010-2019, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
************************************************************************************/
/**
* @file	    mjs_mysql.h
* @version     
* @brief      
* @author   duye
* @date	    2016-12-27
* @note 
*
* 1. 2016-12-27 duye Created this file
*/

#pragma once

#include <string>
#include <vector>
#include <mysql.h>
#include <duye_type.h>
#include <mjs_mysql_result.h>

class MJSMysql {
public:
	class Params {
	public:
		Params() {}
		Params(const std::string& var1) {
			m_params.push_back(var1);
		}

		Params(const std::string& var1, const std::string& var2) {
			m_params.push_back(var1);
			m_params.push_back(var2);
		}	

		Params(const std::string& var1, const std::string& var2, const std::string& var3) {
			m_params.push_back(var1);
			m_params.push_back(var2);
			m_params.push_back(var3);
		}

		Params(const std::string& var1, const std::string& var2
			, const std::string& var3, const std::string& var4) {
			m_params.push_back(var1);
			m_params.push_back(var2);
			m_params.push_back(var3);
			m_params.push_back(var4);
		}

		Params(const std::string& var1, const std::string& var2
			, const std::string& var3, const std::string& var4
			, const std::string& var5) {
			m_params.push_back(var1);
			m_params.push_back(var2);
			m_params.push_back(var3);
			m_params.push_back(var4);
			m_params.push_back(var5);
		}

		Params(const std::string& var1, const std::string& var2
			, const std::string& var3, const std::string& var4
			, const std::string& var5, const std::string& var6) {
			m_params.push_back(var1);
			m_params.push_back(var2);
			m_params.push_back(var3);
			m_params.push_back(var4);
			m_params.push_back(var5);
			m_params.push_back(var6);
		}

		Params(const std::string& var1, const std::string& var2
			, const std::string& var3, const std::string& var4
			, const std::string& var5, const std::string& var6
			, const std::string& var7) {
			m_params.push_back(var1);
			m_params.push_back(var2);
			m_params.push_back(var3);
			m_params.push_back(var4);
			m_params.push_back(var5);
			m_params.push_back(var6);
			m_params.push_back(var7);
		}

		Params(const std::string& var1, const std::string& var2
			, const std::string& var3, const std::string& var4
			, const std::string& var5, const std::string& var6
			, const std::string& var7, const std::string& var8) {
			m_params.push_back(var1);
			m_params.push_back(var2);
			m_params.push_back(var3);
			m_params.push_back(var4);
			m_params.push_back(var5);
			m_params.push_back(var6);
			m_params.push_back(var7);
			m_params.push_back(var8);
		}

		Params(const std::string& var1, const std::string& var2
			, const std::string& var3, const std::string& var4
			, const std::string& var5, const std::string& var6
			, const std::string& var7, const std::string& var8
			, const std::string& var9) {
			m_params.push_back(var1);
			m_params.push_back(var2);
			m_params.push_back(var3);
			m_params.push_back(var4);
			m_params.push_back(var5);
			m_params.push_back(var6);
			m_params.push_back(var7);
			m_params.push_back(var8);
			m_params.push_back(var9);
		}

		bool empty() {
			return m_params.empty();
		}

		bool empty() const {
			return m_params.empty();
		}

		uint32 size() {
			return m_params.size();
		}

		uint32 size() const {
			return m_params.size();
		}

		std::string const operator[](const uint32 i) {
			if (i >= m_params.size()) {
				return "";
			}

			return m_params[i];
		}

		std::string const operator[](const uint32 i) const {
			if (i >= m_params.size()) {
				return "";
			}

			return m_params[i];
		}		

	private:
		std::vector<std::string> m_params;
	};

public:
	MJSMysql();
	~MJSMysql();

	static MJSMysql& ins();

	bool init(const std::string& addr, const uint16 port, const std::string& user, const std::string& pwd, const std::string& database);
	
	int32 execute(const std::string& sql);
	int32 execute(const std::string& sql, const MJSMysql::Params& params);

	bool query(const std::string& sql, MJSMysqlResult& result);
	bool query(const std::string& sql, const MJSMysql::Params& params, MJSMysqlResult& result);

	int32 update(const std::string& sql);
	int32 update(const std::string& sql, const MJSMysql::Params& params);

private:
	bool valid();
	bool joinsql(const std::string& sql, const MJSMysql::Params& params, std::string& out_sql);
	bool commit(const std::string& sql, MJSMysqlResult& result);

private:
	MYSQL* m_conn;
};